﻿using Light.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Light.Framework
{
    /// <summary>
    /// 实体排序对象
    /// </summary>
    [Serializable]
    public class ResultOrder
    {
        Dictionary<string, bool> dic = new Dictionary<string, bool>();

        /// <summary>
        /// 设置排序
        /// </summary>
        /// <param name="name">排序属性，值true表示升序，false表示降序</param>
        /// <returns></returns>
        public bool this[string name]
        {
            get
            {
                if (dic.Keys.Contains(name))
                    return dic[name];
                else
                    return false;
            }
            set
            {
                if (dic.Keys.Contains(name))
                    dic[name] = value;
                else
                    dic.Add(name, value);
            }
        }

        public void Add(string field, bool isAscending)
        {
            if (!dic.Keys.Contains(field))
                dic.Add(field, isAscending);
            else
                dic[field] = isAscending;
        }

        public void Clear()
        {
            dic.Clear();
        }

        /// <summary>
        /// 是否为空
        /// </summary>
        public bool IsEmpty
        {
            get
            {
                return dic.Count == 0;
            }
        }

        /// <summary>
        /// 转对象类型对应的表或视图排序列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public string ToString<T>()
        {
            StringBuilder builder = new StringBuilder();

            List<ColumnInfo> columns = DbMapper.GetColumns<T>();
            Dictionary<string, BelongsInfo> belongsColumns = DbMapper.GetBelongsColumnsDic<T>();
            bool hasBelongs = belongsColumns != null && belongsColumns.Count > 0;
            string tableAlias = DbMapper.PRIMARY_TABLE_ALIAS;

            foreach (var propertyName in dic.Keys)
            {
                if (propertyName.Contains(".")) //包含外键属性，表加上别名
                {
                    string columnName = propertyName;

                    if (hasBelongs) // 使用外键表的表排序
                    {
                        string[] temp = propertyName.Split('.'); // Aaa.Bbb.Ccc => Aaa.Bbb、Ccc
                        string lastPName = temp[temp.Length - 1]; //Ccc
                        string firstPName = propertyName.Substring(0, propertyName.LastIndexOf(".")); //Aaa.Bbb

                        BelongsInfo bc = belongsColumns[firstPName];
                        //找到外键表的列
                        int cascade = propertyName.Split('.').Length;
                        columns = DbMapper.GetColumns(bc.Type, cascade);
                        ColumnInfo column = columns.Find(c => c.PropertyName == lastPName);
                        if (column != null)
                            columnName = column.Name;
                        else
                            throw new Exception("不支持按 " + propertyName + " 排序，属性与数据库字段不匹配。");

                        tableAlias = bc.Alias;
                    }
                    builder.Append(tableAlias + "." + columnName + " " + (dic[propertyName] ? "ASC" : "DESC"));
                }
                else
                {
                    if (hasBelongs)
                        builder.Append(tableAlias + ".");

                    ColumnInfo column = columns.Find(c => c.PropertyName == propertyName);
                    if (column != null)
                        builder.Append(column.Name + " " + (dic[propertyName] ? "ASC" : "DESC"));
                    else
                        throw new Exception("不支持按 " + propertyName + " 排序，属性与数据库字段不匹配。");
                }
                builder.Append(",");
            }
            if (dic.Count > 0)
            {
                builder.Remove(builder.Length - 1, 1);
            }
            else 
            {
                //如果未指定排序值，则按主键ID进行排序
                ColumnInfo primaryKey = DbMapper.GetPrimaryKey<T>();
                if (hasBelongs)
                {
                    builder.Append(tableAlias + "." + primaryKey.Name + " DESC");
                }
                else
                {
                    builder.Append(primaryKey.Name + " DESC");
                }
            }
            return builder.ToString();
        }

        /// <summary>
        ///  转表或视图的排序列
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();

            foreach (var columnName in dic.Keys)
            {
                builder.Append(columnName + " " + (dic[columnName] ? "ASC" : "DESC"));
                builder.Append(",");
            }
            if (dic.Count > 0)
            {
                builder.Remove(builder.Length - 1, 1);
            }
            return builder.ToString();
        }
    }
}
